from sqlalchemy import or_
from datetime import datetime
from flask import current_app
import requests
import json
from app import db
from app.models.user import User


class UserService:
    """小程序用户服务层"""
    
    @staticmethod
    def get_list(page=1, per_page=10, keyword=None, status=None):
        """获取用户列表"""
        query = User.query
        
        # 关键词搜索
        if keyword:
            query = query.filter(or_(
                User.nickname.like(f'%{keyword}%'),
                User.phone.like(f'%{keyword}%')
            ))
        
        # 状态筛选
        if status is not None:
            query = query.filter(User.status == status)
        
        # 按创建时间降序排列
        query = query.order_by(User.created_at.desc())
        
        return query, page, per_page
    
    @staticmethod
    def get_by_id(user_id):
        """根据ID获取用户"""
        return User.query.get(user_id)
    
    @staticmethod
    def update_status(user_id, status):
        """更新用户状态"""
        user = User.query.get(user_id)
        if not user:
            return None
        
        user.status = status
        db.session.commit()
        return user
    
    @staticmethod
    def delete(user_id):
        """删除用户"""
        user = User.query.get(user_id)
        if not user:
            return False
        
        db.session.delete(user)
        db.session.commit()
        return True
    
    @staticmethod
    def wechat_login(code):
        """
        微信登录，获取用户信息，如果是新用户则创建
        
        Args:
            code: 微信登录凭证
            
        Returns:
            tuple: (用户信息字典, 是否新用户)
        """
        # 获取微信配置
        appid = current_app.config['WECHAT_APPID']
        secret = current_app.config['WECHAT_SECRET']
        
        # 调用微信接口获取用户openid
        url = f"https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code"
        
        # 如果是DEBUG模式，可以模拟微信API响应
        if current_app.config['DEBUG'] and code == 'test_code':
            openid = 'test_openid_' + datetime.now().strftime('%Y%m%d%H%M%S')
            unionid = None
        else:
            try:
                response = requests.get(url)
                data = response.json()
                
                if 'errcode' in data and data['errcode'] != 0:
                    error_msg = data.get('errmsg', '未知错误')
                    raise Exception(f"微信API错误: {error_msg}")
                
                openid = data.get('openid')
                unionid = data.get('unionid')
                
                if not openid:
                    raise Exception("获取openid失败")
            except Exception as e:
                current_app.logger.error(f"调用微信API异常: {str(e)}")
                raise Exception(f"微信登录失败: {str(e)}")
        
        # 查询用户是否存在
        user = User.query.filter_by(openid=openid).first()
        is_new_user = False
        
        # 如果用户不存在，创建新用户
        if not user:
            is_new_user = True
            user = User(
                openid=openid,
                unionid=unionid,
                nickname=f"用户{openid[-6:]}",  # 默认昵称
                gender=1,  # 默认为男性，后续在资料完善中修改
                status=2,  # 默认为待审核状态
                last_login_time=datetime.now()
            )
            db.session.add(user)
        else:
            # 更新登录时间和次数
            user.last_login_time = datetime.now()
            user.login_count = (user.login_count or 0) + 1
        
        db.session.commit()
        
        return user.to_dict(), is_new_user
    
    @staticmethod
    def update_user_phone(user_id, phone):
        """
        更新用户手机号（可选功能）
        
        Args:
            user_id: 用户ID
            phone: 手机号
            
        Returns:
            User: 更新后的用户对象
        """
        user = User.query.get(user_id)
        if not user:
            return None
        
        # 检查手机号是否已被其他用户使用
        existing_user = User.query.filter_by(phone=phone).first()
        if existing_user and existing_user.id != user_id:
            raise Exception("该手机号已被其他用户使用")
        
        user.phone = phone
        db.session.commit()
        return user
    
    @staticmethod
    def get_user_by_id(user_id):
        """
        根据ID获取用户
        
        Args:
            user_id: 用户ID
            
        Returns:
            User: 用户对象
        """
        return User.query.get(user_id)
    
    @staticmethod
    def get_user_by_openid(openid):
        """
        根据openid获取用户
        
        Args:
            openid: 微信openid
            
        Returns:
            User: 用户对象
        """
        return User.query.filter_by(openid=openid).first()
    
    @staticmethod
    def get_user_by_phone(phone):
        """
        根据手机号获取用户
        
        Args:
            phone: 手机号
            
        Returns:
            User: 用户对象
        """
        return User.query.filter_by(phone=phone).first() 